﻿package makeeasier.filters {
	
	import flash.display.*;
	import flash.geom.*;
	import flash.filters.*;
	import flash.events.*;
	
	public class MirrorFilter extends Sprite {
		
		private var src:DisplayObject;
		private var new_bmd:BitmapData;
		private var alphas:Array;
		private var ratios:Array;
		private var angle:Number;
		private var blurPercent:Number;
		//private var area:Rectangle;
		private var startX:Number;
		private var startY:Number;
		private var output:BitmapData;
		private var output_bitmap:BitmapData;
		private var output_sprite:Bitmap;
		
		private var ImageMask:Sprite;
		
		private var picture:Sprite;
		private var reflection:BitmapData;
		private var reflectionHolder:Bitmap;
		
		public function MirrorFilter(it:DisplayObject, sta:Number = 0 , stb:Number = 0, alp:Array = null, rat:Array = null, ang:Number=0, bl:Number=0){
			src = it;
			alphas = (alp!=null ? alp : [0.5,0]);
			ratios = (rat!=null ? rat : [0,180]);
			angle = ang;
			//area = (ar!=null ? ar : new Rectangle(0,0,it.width,it.height));
			startX = sta;
			startY = stb;
			blurPercent = bl;
			addEventListener(Event.ADDED_TO_STAGE, UpdateFilter);
			addEventListener(Event.ENTER_FRAME, UpdatePlacement);
			src.addEventListener(Event.ENTER_FRAME, UpdateFilter);
		}
		
		private function makeReflection(){
			
			//Adimlar
			//1. resmi ters cevirerek komple kopyala
			//2. resmin istenen Y kismina gore sil
			//3. mirror icin temp gradient hazirla ve bunla resme komple mirror etkisi ver
			
			// 1
			reflection = new BitmapData(src.width, src.height, true, 0x00ffffff);
			
			var flipMatrix:Matrix = new Matrix();
			flipMatrix.rotate(Math.PI);
			flipMatrix.scale( -1, 1 );
			flipMatrix.translate(0, src.height);
			flipMatrix.translate(-startX,-startY);
			
			reflection.draw(src, flipMatrix);
			
			for (var i:int = 0; i < src.height; i++) {
				var rowFactor:Number = Math.max(0, 0.5 - (i / src.height));
				for (var j:int = 0; j < src.width; j++) {
					var pixelColor:uint = reflection.getPixel32(j, i);
					var pixelAlpha:uint = pixelColor >> 24 & 0xff;
					var pixelRGB:uint = pixelColor & 0xffffff;
					var resultAlpha:uint = pixelAlpha * rowFactor;
					reflection.setPixel32(j, i, resultAlpha << 24 | pixelRGB);
				}
			}
			
			//reflection.applyFilter(reflection, reflection.rect, new Point(0, 0), new BlurFilter(4, 4, 3));
			
			reflectionHolder = new Bitmap(reflection);
			reflectionHolder.y = src.y + src.height;
			reflectionHolder.x = src.x;
			//reflectionHolder.filters = [new BlurFilter(4, 4, 3)]; // Alternative blur method
			
			//addChild(reflectionHolder);
			output = reflection.clone();
			
			/*
			//3
			TemporaryMirrorHolder = new Sprite();
			var fillType:String = GradientType.LINEAR;
			var colors:Array = [0xFF0000, 0xFF0000];
			var matr:Matrix = new Matrix();
			matr.createGradientBox(src.width, src.height, angle, 0, 0);
			var spreadMethod:String = SpreadMethod.PAD;
			TemporaryMirrorHolder.graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod, InterpolationMethod.LINEAR_RGB, 0);
			TemporaryMirrorHolder.graphics.drawRect(0,0,src.width,src.height);
			
			TemporaryMirrorBitmapData = new BitmapData(src.width, src.height, true, 0x00FFFFFF);
			TemporaryMirrorBitmapData.draw(TemporaryMirrorHolder,null, null, "normal",null, true);
			
			MirrorImageBitmapData = new BitmapData(src.width, src.height, true, 0);
			MirrorImageBitmapData = reflection.clone();
			MirrorImageBitmapData.copyChannel(TemporaryMirrorBitmapData, new Rectangle(0, 0, src.width, src.height), new Point(0,0), BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA);
			
			output = MirrorImageBitmapData.clone();
			*/
			
			/*
			bmd = new BitmapData(src.width, src.height, true, 0);
			bmd.draw(src);
			new_bmd = new BitmapData(src.width, src.height, true, 0);
			var rc:Sprite = new Sprite();
			var fillType:String = GradientType.LINEAR;
			var colors:Array = [0xFFFFFF, 0xFFFFFF];
			var matr:Matrix = new Matrix();
			matr.createGradientBox(src.width, src.height, angle, 0, 0);
			var spreadMethod:String = SpreadMethod.PAD;
			rc.graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);  
			rc.graphics.drawRect(0,0,src.width,src.height);
			
			var rcalpha:BitmapData = new BitmapData(rc.width, rc.height, true, 0);
			rcalpha.draw(rc);
			//output = rcalpha;
			
			for( var i=area.y; i<area.height; i++ ){
				new_bmd.copyPixels(bmd, new Rectangle(area.x,i,area.width,1), new Point(0,(area.height-1)-i), null, null, false);
			}
			if ( blurPercent > 0 ){
				new_bmd.applyFilter(new_bmd, area, new Point(0,0), new BlurFilter(blurPercent,blurPercent, 3));
			}
			new_bmd.copyChannel(rcalpha, area, new Point(0,area.y), 8, 8);
			output = new_bmd;
			*/
		}
		
		private function UpdateFilter(e:Event){
			trace("updating");
			var t = src as Sprite;
			try{
				t.removeChild(t.getChildByName("reflection"));
			} catch(err){
				
			}
			makeReflection();
			var outp:Bitmap = new Bitmap(out(),PixelSnapping.AUTO,true);
			outp.name = "reflection";
			addChild(outp);
		}
		
		private function UpdatePlacement(e:Event){
			x = src.x;
			y = src.height+src.y;
		}
		
		public function out():BitmapData{
			return output;
		}
		
		public function get source():*{
			return src;
		}
	}
	
}